home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-03-20 | 18.5 KB | 645 lines | [TEXT/MPS ] |
- /*---------------------------------------------------------------------------
- FILENAME
- OldAPIMessageIntf.c
-
- DESCRIPTION
- This module contains the routines which implement the old API messages
- that the LaserWriter SC driver overrides. Much of the logic in this
- module was gleaned from the original LaserWriter IISC driver, and so
- some of the calulations may seem a little strange. In order to maintain
- compatibility with the old driver's logic, we must preserve much of the
- old logic.
-
- COPYRIGHT
- Copyright Apple Computer, Inc. 1989-1992
- All rights reserved.
-
- INTERFACE ROUTINES:
-
- SD_PrValidate
- SD_ConvertPrintRecordTo
- SD_ConvertPrintRecordFrom
-
- -------------------------------------------------------------------------------- */
-
- // Include the standard Mac header files
- #include "MacIncludes.h"
-
- // Include the new QuickDraw GX graphics header files
- #include <GXGraphics.h>
- #include <GraphicsLibraries.h>
- #include <GXMath.h>
-
- // Include the required Printing Manager header files
- #include <GXPrinting.h>
- #include <GXPrinterDrivers.h>
- #include <Collections.h>
- #include <GXMessages.h>
-
- // Include the internal driver constants and types used by this module
- #include "LaserSCResources.h"
- #include "OldAPIMessageIntf.h"
-
-
- /***************************************************************************************
- * INTERNAL ROUTINES *
- ***************************************************************************************/
-
-
- /****************************************************************************************
-
- EmulatePages
-
- function:
- This function takes a paper rectangle, and computes the rPage
- rectangle for it. It uses the old LaserWriter IISC driver's page size
- calculation "algorithm" (if it can be called such).
-
- parameters:
- hPrint target print record whose rPage rect is updated
-
- returns:
- none
-
- ****************************************************************************************/
- void EmulatePages(THPrint hPrint)
- {
- TPrInfo *pPrInfo;
- TPrStl *pPrStl;
- short dvPaper; // the "calculated" paper sizes
- short dhPaper;
- short dvPage; // the "calculated" page sizes
- short dhPage;
- short iOneFourth; // fudge factors which don't quite equal their names
- short iTwoFifths;
- short iVMaxInch; // memory limitation on the page sizes.
- short iHMaxBytes;
- short scanBits; // the eventual # of bits across a line on the page (truncated)
- short scanLines; // the eventual # of lines on the page (truncated)
- short iTemp; // temporary swapping variable for landscape
- short hOff; // used to calculated the offset paper rectangle
- short vOff;
-
-
- pPrInfo = &((*hPrint)->prInfo);
- pPrStl = &((*hPrint)->prStl);
-
-
- dvPaper = (pPrStl->iPageV * pPrInfo->iVRes) / kMysticPaperFract;
- dhPaper = (pPrStl->iPageH * pPrInfo->iHRes) / kMysticPaperFract;
-
-
- // Weird fudge factors from Dave Casseres. No, I don't understand them. No,
- // he apparently doesn't either, anymore.
-
- iOneFourth = (pPrInfo->iHRes + 2) / 4; // this isn't even 1/4th.
- iTwoFifths = ((pPrInfo->iHRes << 2) + 5) / 10; // nor is this 2/5ths!
-
-
- // Boundary condition for large page sizes (legal > 1400 which is 11.666666667").
- // If the paper is smaller than that, then we just do the regular calculation.
- // Otherwise, we restrict the size to 12.5" on the IISC (25/2). Further, we
- // restrict the horizontal dimensions to 6.72 inches (memory limitation on 1 Mb printers
-
- if (pPrStl->iPageV <= 1400)
- {
- iVMaxInch = pPrStl->iPageV;
- iHMaxBytes = kLetterRowBytes;
- }
- else
- {
- iVMaxInch = (25 * kMysticPaperFract) / 2;
- iHMaxBytes = kLegalRowBytes;
- }
-
-
- // Force the horizontal dimension to fit within the laser's restrictions:
- // iHMaxBytes was just set. For letter, it's 8" (300 rowBytes). Multiply by the
- // horizontal resolution (say 72), and divide by high-resolution (300 dpi).
- // Multiply by 8 (<< 3), since we want coordinates, and the iHMaxBytes is
- // a byte count. Always do divisions last, in order to keep precision.
- // dhPaper is the paper size horizontally in rendering units (72 or 300).
- // It really ought to be in one unit or the other, but in emulation mode,
- // it's in whatever the app selected. We force the page size to fit within
- // the laser's restricted area by forcing about a 1/4" border. We do the same
- // vertically, with approximately a 2/5" border total. We truncate the results
- // (why to 16ths and to 2nds? I don't know).
-
- scanBits = ((iHMaxBytes * pPrInfo->iHRes) << 3) / kHorizHighRes;
- if (scanBits > (dhPaper - iOneFourth))
- scanBits = dhPaper - iOneFourth;
- scanBits = (scanBits >> 4) << 4; // number of bits on a single line
-
-
- scanLines = (iVMaxInch * pPrInfo->iVRes) / iPrPgFract;
- if (scanLines > (dvPaper - iTwoFifths))
- scanLines = dvPaper - iTwoFifths;
- scanLines = (scanLines >> 1) << 1; // number of lines on the page
-
-
- // set the page size based on the orientation. Portrait uses the default
- // definitions: bits for horizontal and lines for vertical.
-
- if ( TestBit((*hPrint)->prStl.wDev, kPortraitBit) )
- {
- dhPage = scanBits;
- dvPage = scanLines;
- }
- else // landscape
- {
- dhPage = scanLines;
- dvPage = scanBits;
-
- // Reverse the meanings of paper in landscape as well.
- iTemp = dhPaper;
- dhPaper = dvPaper;
- dvPaper = iTemp;
- }
-
- SetRect( &(pPrInfo->rPage), 0, 0, dhPage, dvPage );
-
- // Create the paper size and store it in the print record
-
- hOff = (dhPage - dhPaper) / 2;
- vOff = (dvPage - dvPaper) / 2;
- SetRect( & ((*hPrint)->rPaper) , hOff, vOff, dhPaper+hOff, dvPaper+vOff );
-
- // Preserve the rPaper rectangle in the printX array starting at word 5. This is done
- // to maintain compatibility with the old LaserWriter SC driver
- {
- BlockMove((Ptr) &((*hPrint)->rPaper), (Ptr) &((*hPrint)->printX[5]), sizeof(Rect));
- }
- }
- /* EmulatePages */
-
-
- /****************************************************************************************
-
- HandleZoom
-
- function:
- This function handles zoom factors from PageSetup. How does zooming work?
- What we do is trick the application into doing the work for us by returning a
- page size bigger than actual. Thus when we render this into the original page
- size, we get a reduced image.
-
- parameters:
- hPrint handle to the print record to change
-
- returns:
- none
-
- ****************************************************************************************/
-
- void HandleZoom(THPrint hPrint)
- {
- gxUniversalPrintRecordPtr pUniv;
- Fixed zoomFactor;
- Rect tempRect;
-
- // Convert print record into the universal form
- SD_ConvertPrintRecordTo(hPrint);
-
- pUniv = (gxUniversalPrintRecordPtr) *hPrint;
-
- // Convert the reduction factor into a fixed zoom value
- zoomFactor = FixRatio(100, pUniv->reduction );
-
- // Notice that we don't zoom the device specific size, since zoom
- // factors "just" trick out the application side of things
-
- tempRect = pUniv->appPage;
- SetRect(&tempRect, FixRound( FixMul( (tempRect.left << 16), zoomFactor) ),
- FixRound( FixMul( (tempRect.top << 16), zoomFactor) ),
- FixRound( FixMul( (tempRect.right << 16), zoomFactor) ),
- FixRound( FixMul( (tempRect.bottom << 16),zoomFactor) ));
- pUniv->appPage = tempRect;
-
- tempRect = pUniv->appPaper;
- SetRect(&tempRect, FixRound( FixMul( (tempRect.left << 16), zoomFactor) ),
- FixRound( FixMul( (tempRect.top << 16), zoomFactor) ),
- FixRound( FixMul( (tempRect.right << 16), zoomFactor) ),
- FixRound( FixMul( (tempRect.bottom << 16),zoomFactor) ));
- pUniv->appPaper = tempRect;
-
-
- // Convert the print record back into the specific driver form
- SD_ConvertPrintRecordFrom(hPrint);
- }
- /* HandleZoom */
-
-
- /****************************************************************************************
-
- UpdatePrInfoPt
-
- function:
- This function updates the prInfoPT portion of the print record. The logic
- for updating the prInfoPT structure comes from the original LaserWriter
- SC driver.
-
- parameters:
- hPrint handle to the print record to change
- calcDeviceRects true to calc device rectangles
-
- returns:
- none
-
- ****************************************************************************************/
- void UpdatePrInfoPt(THPrint hPrint, Boolean calcDeviceRects)
- {
- Rect tempRect;
- TPPrint pPrint = *hPrint;
- short precFlags;
-
- // Initially assume the prInfoPT structure will be like that of prInfo
-
- pPrint->prInfoPT.iHRes = pPrint->prInfo.iHRes;
- pPrint->prInfoPT.iVRes = pPrint->prInfo.iVRes;
- pPrint->prInfoPT.rPage = pPrint->prInfo.rPage;
-
- precFlags = pPrint->prXInfo.iBandV;
-
- if (
- (calcDeviceRects) &&
- ( !TestBit(precFlags, kDevResBit) ) // T => We're not imaging at device resolution
- )
- {
- short theRes = pPrint->prInfoPT.iHRes;
- Fixed scale;
-
-
- // Compute the new resolution based upon the scaling factors
-
- if ( TestBit(precFlags, kScale75Bit) )
- {
- theRes = (theRes << 2) / 3;
- }
- else
- if ( TestBit(precFlags, kScale50Bit) )
- {
- theRes <<= 1;
- }
- else
- if ( TestBit(precFlags, kScale25Bit) )
- theRes <<= 2;
-
- // Are we doing exact bitmap scaling, or scaling to the resolution of the device?
-
- if ( TestBit(precFlags, kExactBitBit) )
- {
- scale = FixRatio(kHorizHighExactRes, theRes);
- theRes = kHorizHighExactRes;
- }
- else
- {
- scale = FixRatio(kHorizHighRes, theRes);
- theRes = kHorizHighRes;
- }
-
- // Update the resolution fields
-
- pPrint->prInfoPT.iHRes = theRes;
- pPrint->prInfoPT.iVRes = theRes; // the old driver doesn't update the iVRes field, but we will
-
- // Now we need to calculate the new rPage
- tempRect = pPrint->prInfoPT.rPage;
-
- // Calculate the device resolution rectangle
- SetRect(&tempRect, FixRound( FixMul( (tempRect.left << 16), scale) ),
- FixRound( FixMul( (tempRect.top << 16), scale) ),
- FixRound( FixMul( (tempRect.right << 16), scale) ),
- FixRound( FixMul( (tempRect.bottom << 16), scale) ));
-
- // Store away the device page size
- (*hPrint)->prInfoPT.rPage = tempRect;
- }
-
- }
- /* UpdatePrInfoPt */
-
-
-
- /****************************************************************************************
-
- UpdatePrintRecord
-
- function:
- This function updates the print record based upon the application's
- calls to PrGeneral.
-
- parameters:
- hPrint print record to update
- calcDeviceRects true to calculate device rectangles, false to copy from apps
-
- returns:
- none
-
- ****************************************************************************************/
- void UpdatePrintRecord(THPrint hPrint, Boolean calcDeviceRects)
- {
- // emulate those crazy old style pages
- EmulatePages(hPrint);
-
- // Handle the case of zoom factors by scaling the rectangles
- HandleZoom(hPrint);
-
- // Compute and fill in the devPage rectangle and the remainder of prInfoPT
- UpdatePrInfoPt(hPrint, calcDeviceRects);
- }
- /* UpdatePrintRecord */
-
-
-
- /***************************************************************************************
- * INTERFACE ROUTINES *
- ***************************************************************************************/
-
- /****************************************************************************************
-
- SD_PrValidate
-
- function:
- This function validates the print record. If the passed-in print record contains
- valid information (see below), then it's updated based upon the application's
- calls to Prgeneral. Otherwise, it is unchanged, and the return code is true.
- Otherwise, the print record is defaulted (with SD_PrintDefault), and the
- return value is false.
-
- Validation:
- The upper byte of the wDev must be the ID of the device
- (kPrinterID in Resources.h).
- The version of the print record must be current
- (oldLWSCPrintRecordVersion in Resources.h)
- (For new print records, we will validate all of the fields which are
- public (e.g., paper size), not just these fields)
-
- parameters:
- hPrint print record to validate
- wasChanged returns true if print record was invalid; false otherwise
-
- returns:
- OSErr
-
- ****************************************************************************************/
- OSErr SD_PrValidate(THPrint hPrint, Boolean *wasChanged)
- {
- short wDev; // device specific stuff in this word
- Boolean returnVal = true; // initialize return value to "invalid"
- // Why is true == "invalid"? Nobody knows!
-
- // check the wDev. The upper byte must be equal to kPrinterID. We get the
- // wDev, and shift wDev DOWN eight.
-
- wDev = (*hPrint)->prStl.wDev;
- wDev >>= 8; // get just the device ID
-
-
- // If the device id is equal, then check the version number of the print record.
- // Only if that is also equal to the current version, will we return false (valid).
-
- if (wDev == kPrinterID)
- if ( ((*hPrint)->iPrVersion) == oldLWSCPrintRecordVersion )
- returnVal = false;
-
-
- // If the print record is not valid, then return the default print record.
- // Otherwise, update the print record, based on the application's calls
- // to PrGeneral.
-
- if (returnVal)
- PrintDefault(hPrint);
- else
- UpdatePrintRecord(hPrint, false);
-
- *wasChanged = returnVal;
-
- return(noErr);
- }
- /* SD_PrValidate */
-
-
- /****************************************************************************************
-
- SD_OpenDoc
-
- function:
- SD_OpenDoc is the first call for printing an old style document.
-
-
- ****************************************************************************************/
- OSErr SD_OpenDoc( THPrint hPrint, // old-style print record for this document
- TPPrPort *printingPort)
- {
- OSErr anErr;
-
- UpdatePrintRecord(hPrint, true);
-
- anErr = Forward_GXPrOpenDoc(hPrint, printingPort);
-
- return(anErr);
-
- } /* SD_OpenDoc */
-
- /****************************************************************************************
-
- SD_ConvertPrintRecordTo
-
- function:
- SD_ConvertPrintRecordTo converts the fields of the print record for
- the device into the universal print record format.
-
- parameters:
- hPrint print record to convert to universal format
-
- returns:
- OSErr
-
- ****************************************************************************************/
- OSErr SD_ConvertPrintRecordTo(THPrint hPrint)
- {
- gxUniversalPrintRecordPtr pUniv;
- TPPrint pPrint;
- short options = 0;
- short oldFlags;
-
- pUniv = (gxUniversalPrintRecordPtr) *hPrint;
- pPrint = *hPrint;
-
- // Convert paper feed settings (old and univ setting are switched)
-
- if ( pPrint->prStl.feed == oldPRECAutoFeed )
- pUniv->feed = gxAutoFeed;
- else
- pUniv->feed = gxManualFeed;
-
- // Determine the new options field settings; univ and specific share this location
-
- oldFlags = pPrint->prXInfo.iBandV;
-
- if ( TestBit(oldFlags, kTextSmoothingBit) )
- options |= gxTextSmoothing;
-
- if ( TestBit(oldFlags, kExactBitBit) )
- options |= gxPreciseBitmap;
-
- if ( TestBit(oldFlags, kDevResBit) )
- pUniv->appHRes = pUniv->appVRes = 300;
- else
- pUniv->appHRes = pUniv->appVRes = 72;
-
- pUniv->options = options;
-
- // We need to save the settings of the other flag bits from the old print record (e.g. fGrayScale,
- // fDraftBits, etc.). We save them in printX[18].
- pUniv->printX[18] = oldFlags;
-
- // Now determine the scaling factor, if any, and designate the proper dialog button that
- // corresponds to the scaling factor. The userCluster1 field specifies the dialog button.
-
- if ( TestBit(oldFlags, kScale75Bit) )
- {
- pUniv->reduction = 75;
- pUniv->userCluster1 = 1;
- }
- else
- if ( TestBit(oldFlags, kScale50Bit) )
- {
- pUniv->reduction = 50;
- pUniv->userCluster1 = 2;
- }
- else
- if ( TestBit(oldFlags, kScale25Bit) )
- {
- pUniv->reduction = 25;
- pUniv->userCluster1 = 3;
- }
- else // T => No scaling being performed
- {
- pUniv->reduction = 100;
- pUniv->userCluster1 = 0;
- }
-
- // Set the orientation properly
-
- if ( TestBit(pPrint->prStl.wDev, kPortraitBit) )
- pUniv->orientation = gxPortraitOrientation;
- else
- pUniv->orientation = gxLandscapeOrientation;
-
- // Always assign these fields explicit values to ensure they don't cause problems
-
- pUniv->qualityMode = gxBestQuality;
- pUniv->firstTray = gxFirstTray;
- pUniv->remainingTray = gxFirstTray;
- pUniv->coverPage = gxNoCoverPage;
- pUniv->headMotion = gxUnidirectionalMotion;
- pUniv->saveFile = gxNoFile;
-
- return(noErr);
- }
- /* SD_ConvertPrintRecordTo */
-
-
- /****************************************************************************************
-
- SD_ConvertPrintRecordFrom
-
- function:
- SD_ConvertPrintRecordFrom converts the fields of the print record in
- universal print record format into the print record format for the
- specific device.
-
- parameters:
- hPrint print record to convert to device specific format
-
- returns:
- OSErr
-
- ****************************************************************************************/
- OSErr SD_ConvertPrintRecordFrom(THPrint hPrint)
- {
- gxUniversalPrintRecordPtr pUniv;
- TPPrint pPrint;
- short iBandV = 0;
- short oldOptions;
- short savedOldFlags;
-
- pUniv = (gxUniversalPrintRecordPtr) *hPrint;
- pPrint = *hPrint;
-
- // Set the orientation properly
-
- if (pUniv->orientation == gxPortraitOrientation)
- pPrint->prStl.wDev |= kPortraitBit;
- else
- pPrint->prStl.wDev &= ~kPortraitBit;
-
- // Convert paper feed settings (old and univ setting are switched)
-
- if ( pUniv->feed == gxAutoFeed )
- pPrint->prStl.feed = oldPRECAutoFeed;
- else
- pPrint->prStl.feed = oldPRECManualFeed;
-
- // Set the flags in the iBandV field of the print record
-
- oldOptions = pUniv->options;
-
- if ( TestBit(oldOptions, gxTextSmoothing) )
- iBandV |= kTextSmoothingBit;
-
- switch( pUniv->userCluster1 ) // Based on the scaling dialog button setting, set the scaling factor
- {
- case 0:
- break;
-
- case 1:
- iBandV |= kScale75Bit;
- break;
-
- case 2:
- iBandV |= kScale50Bit;
- break;
-
- case 3:
- iBandV |= kScale25Bit;
- break;
- }
-
- if ( TestBit(oldOptions, gxPreciseBitmap) )
- iBandV |= kExactBitBit;
-
- savedOldFlags = pUniv->printX[18];
-
- if (pUniv->appHRes != 72)
- iBandV |= kDevResBit;
-
- if ( TestBit(savedOldFlags, kDraftBitsBit) )
- iBandV |= kDraftBitsBit;
-
- if ( TestBit(savedOldFlags, kAbortChkBit) )
- iBandV |= kAbortChkBit;
-
- if ( TestBit(savedOldFlags, kGrayScaleBit) )
- iBandV |= kGrayScaleBit;
-
- // Initialize the remaining fields in the TPrXInfo structure
-
- pPrint->prXInfo.iBandV = iBandV;
- pPrint->prXInfo.iBandH = 0;
- pPrint->prXInfo.iDevBytes = 0;
- pPrint->prXInfo.iBands = 0;
- pPrint->prXInfo.bPatScale = kPatScale;
- pPrint->prXInfo.bUlThick = 0;
- pPrint->prXInfo.bUlOffset = 0;
- pPrint->prXInfo.bUlShadow = 0;
- pPrint->prXInfo.scan = scanTB;
- pPrint->prXInfo.bXInfoX = 0;
-
- pPrint->printX[18] = 0;
-
- return(noErr);
- }
- /* SD_ConvertPrintRecordFrom */
-